evtchn: Do not free d->poll_mask until domain is being deallocated.
authorKeir Fraser <keir.fraser@citrix.com>
Thu, 24 Dec 2009 12:14:09 +0000 (12:14 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Thu, 24 Dec 2009 12:14:09 +0000 (12:14 +0000)
Avoids crash on dereference of poll_mask after domain_kill().

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
xen/common/domain.c
xen/common/event_channel.c
xen/include/xen/sched.h

index b961b104d1b3d2473aa140c182e64e01fd24c786..e4a29f88420bd5641c19dff04731b99fb76fe085 100644 (file)
@@ -317,7 +317,10 @@ struct domain *domain_create(
     if ( init_status & INIT_gnttab )
         grant_table_destroy(d);
     if ( init_status & INIT_evtchn )
+    {
         evtchn_destroy(d);
+        evtchn_destroy_final(d);
+    }
     if ( init_status & INIT_rangeset )
         rangeset_domain_destroy(d);
     if ( init_status & INIT_xsm )
@@ -606,6 +609,8 @@ static void complete_domain_destroy(struct rcu_head *head)
     if ( d->target != NULL )
         put_domain(d->target);
 
+    evtchn_destroy_final(d);
+
     xfree(d->pirq_mask);
     xfree(d->pirq_to_evtchn);
 
index d052f15980d1a75d2ba9a522cb3e881a26b53132..29c515cf0cee5d519a875a0201d603663ba1ce07 100644 (file)
@@ -1052,13 +1052,18 @@ void evtchn_destroy(struct domain *d)
         d->evtchn[i] = NULL;
     }
     spin_unlock(&d->event_lock);
+}
+
 
+void evtchn_destroy_final(struct domain *d)
+{
 #if MAX_VIRT_CPUS > BITS_PER_LONG
     xfree(d->poll_mask);
     d->poll_mask = NULL;
 #endif
 }
 
+
 static void domain_dump_evtchn_info(struct domain *d)
 {
     unsigned int port;
index c637e11b6917b98486421a0da91fb3d4a7758602..d9180773f94664656639913a6afede4db3984faa 100644 (file)
@@ -67,8 +67,9 @@ struct evtchn
 #endif
 };
 
-int  evtchn_init(struct domain *d);
-void evtchn_destroy(struct domain *d);
+int  evtchn_init(struct domain *d); /* from domain_create */
+void evtchn_destroy(struct domain *d); /* from domain_kill */
+void evtchn_destroy_final(struct domain *d); /* from complete_domain_destroy */
 
 struct vcpu 
 {